<?php //$Rev:: 34         $ // DO NOT REMOVE

error_reporting(E_ALL);

/**
 * SFLAP Class
 * 
 * @author Andrew Heebner <andrew@evilwalrus.com> 
 * @version $Revision: 34 $
 * @require PHP 5.0
 */
class SFLAP
{

	public $core;
    private $count;

	/**
	 * __construct: SFLAP constructor
	 * 
	 * @param object $object Object to store for parent referencing
	 * @access public 
	 * @return void 
	 */
	public function __construct(ATAC $object)
	{
		$this->core = $object;
        $this->aim_seed_trackid();
	} 

	/**
	 * __destruct: SFLAP destructor
	 * 
	 * @access public 
	 * @return void 
	 */
	public function __destruct()
	{
		unset($this->core);
	} 

	/**
	 * __call: SFLAP invalid method parser
	 * 
	 * @param string $method Invalid method called
	 * @access private 
	 * @return void 
	 * @throws ATACException
	 */
	public function __call($method, $args)
	{
		throw new ATACException('Invalid method called => (' . __CLASS__ . '::' . $method . ')');
	}

	/**
	 * aim_seed_trackid: Seed the random number generator for tracking numbers
	 * 
	 * @access private 
	 * @return void
     * @proto void aim_seed_trackid(void)
	 */
    private function aim_seed_trackid()
    {
		mt_srand((double)microtime() * 1000000);
		$this->count = (int)mt_rand(1, 10000);
    }

	/**
	 * aim_sflap_send: Send an SFLAP packet to the TOC server
	 * 
	 * @param integer $type SFLAP type to send packet as
     * @param string  $data Data to send in packet
	 * @access public
	 * @return boolean
     * @proto boolean aim_sflap_send(integer sflap_type, string data)
	 */
    public function aim_sflap_send($type, $data)
    {
		$data = (strlen($data) > SFLAP_MAX_LENGTH) ? substr($data, 0, SFLAP_MAX_LENGTH - 1) . "\0" : $data . "\0";
		$message = pack("aCnna*", '*', $type, $this->count, strlen($data), $data);
		$result = $this->aim_sflap_raw($message);
		$this->count++;
		return $result;
    }

	/**
	 * aim_sflap_recv: Recieve SFLAP data from the TOC server
	 * 
	 * @access public 
	 * @return void
     * @proto void aim_sflap_recv(void)
	 */
    public function aim_sflap_recv()
    {
		$header = fread($this->core->resource, SFLAP_HEADER_LEN);

		try {
			if (!$_head = @unpack("aasterisk/CframeType/nseqNum/ndataLen", $header)) {
                $this->core->aim_debug('Received keepalive command', AIM_RECV);
			}
		} catch(ATACException $ex) {
			$ex->display();
		}

        // ensure we unpack the proper way
		$packet = @fread($this->core->resource, $_head['dataLen']);
        switch ($_head['frameType']) {
            case SFLAP_TYPE_SIGNON:
                $_pack = unpack("Ndata", $packet);
                break;
            case SFLAP_TYPE_KEEPALIVE:
                $this->core->aim_debug('Received keepalive packet');
                break;
            default:
                $_pack = unpack("a*data", $packet);
                break;
        }

        $matches = explode(':', $_pack['data'], 2);
        $matches[1] = (empty($matches[1])) ? '' : $matches[1];
        $this->core->parser->aim_parse_command($matches[0], $matches[1]);
    }

	/**
	 * aim_sflap_raw: Send raw SFLAP data to the TOC server
	 * 
	 * @access public 
	 * @return boolean
     * @proto boolean aim_sflap_raw(string data)
	 */
    public function aim_sflap_raw($data)
    {
        return fwrite($this->core->resource, $data);
    }

	/**
	 * aim_sflap_signon: Send the initial signon to the server
	 * 
	 * @access public 
	 * @return boolean
     * @proto boolean aim_sflap_signon(void)
	 */
    public function aim_sflap_signon()
    {
        $data = pack("Nnna" . strlen($this->core->user['screenname']), 1, 1, strlen($this->core->user['screenname']), $this->core->user['screenname']);
        $result = $this->aim_sflap_send(SFLAP_TYPE_SIGNON, $data);
        return $result;
    }

	/**
	 * aim_sflap_toc_signon: Send full TOC2 signon sequence to TOC sever
	 * 
	 * @access public 
	 * @return boolean
     * @proto boolean aim_sflap_toc_signon(void)
	 */
    public function aim_sflap_toc_signon()
    {
        $signon = sprintf('toc2_login %s %s "%s" %s "%s" "%s" 160 %s "%s" "%s" 3 0 30303 %s %s',
                                  (($this->core->user['use_icq']!==false) ? $this->core->conn['auth_serv']['icq'] : $this->core->conn['auth_serv']['aim']),
                                  $this->core->conn['auth_port'],
                                  $this->core->user['screenname'],
                                  $this->core->aim_roast_pass($this->core->user['password']),
                                  $this->core->conn['language'],
                                  'TIC:\Revision: 1.61',
                                  "US",
                                  "", // ??
                                  "", // ??
                                  "-kentucky -utf8 -preakness",
                                  $this->core->aim_toc2_hash($this->core->user['screenname'], $this->core->user['password']) );

        $result = $this->aim_sflap_send(SFLAP_TYPE_DATA, $signon);
        return $result;
    }

}

?>